﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nova.Parsing.GoldParser.Semantic;
using Nova.Parsing.Tokens;

namespace Nova.Parsing.Constructs
{
    public sealed class InstructionSetConstruct : NovaConstruct, IEnumerable<InstructionBlockConstruct>
    {
        private InstructionBlockConstruct m_CurrentInstruction;
        private InstructionSetConstruct m_NextSet;

        [Rule(@"<Instruction Blocks> ::= <Instruction Block> <Instruction Blocks>")]
        [Rule(@"<Instruction Blocks> ::= <Instruction Block>")]
        public InstructionSetConstruct(InstructionBlockConstruct instruction, InstructionSetConstruct nextSet)
        {
            m_CurrentInstruction = instruction;
            m_NextSet = nextSet;
        }

        public InstructionBlockConstruct CurrentInstruction
        {
            get { return m_CurrentInstruction; }
        }

        public InstructionSetConstruct NextInstructionSet
        {
            get { return m_NextSet; }
        }

        public IEnumerator<InstructionBlockConstruct> GetEnumerator()
        {
            for (InstructionSetConstruct set = this; set != null; set = set.NextInstructionSet)
            {
                if (set.CurrentInstruction != null)
                {
                    yield return set.CurrentInstruction;
                }
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public sealed class InstructionBlockConstruct : NovaConstruct
    {
        private StatementSet m_Statements;
        private string m_InstructionName;

        [Rule(@"<Instruction Block> ::= instruction '(' Identifier ')' <Statement Block>")]
        public InstructionBlockConstruct(
            IgnoredToken iA, IgnoredToken iB, Identifier identifer, IgnoredToken iC, StatementBlock statements)
        {
            m_InstructionName = (string)identifer.Value;
            m_Statements = statements.Statements;
        }

        public StatementSet Statements
        {
            get { return m_Statements; }
        }

        public string InstructionName
        {
            get { return m_InstructionName; }
        }
    }
}
